package common.project.epic.ui;

import java.util.Date;

import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.bluetooth.BluetoothAdapter;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.database.Cursor;
import android.graphics.Typeface;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
import android.util.Log;
import android.util.TypedValue;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.ListAdapter;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;
import android.widget.Toast;

import common.project.epic.core.EpicSynch;
import common.project.epic.core.IEpicSynch;
import common.project.epic.core.IOEpicService;
import common.project.epic.core.LocationEpicService;
import common.project.epic.db.EpicDBAdapter;
public class Epic extends Activity {
	
	public static final String TAG = "Epic: Epic Activity";
    public static final boolean DEBUG = EpicDebugUI.DEBUG;

	// GridView item position IDs
	private final static int  NEW_MSG = 0;
	private final static int ALL_MSG = 1;
	private final static int SETTINGS = 2;
	private final static int PROFILE = 3;
	private String[] label_array = new String[4];
	// the GridView contains the Views that activate the following Activities: 
	// 1. EpicMsg: create a new message
	// 2. EpicMsgList: show all messages 
	// 3. EpicSettings: manage application settings
	// 4. EpicProfile: manage user profile
	private GridView gridview;
	// simulate gallery with HorizontalListView
	private HorizontalListView myListView;
	private EpicDBAdapter dbHelper;
	private Cursor cursor;
	
	private static final int REQUEST_ENABLE_BT = 1;
	private static final int REQUEST_DISCOVERABLE_BT = 2;
	private static final int PROGRESS_DIALOG = 0;
	private ProgressDialog progressDialog;
	private BluetoothAdapter bluetoothAdapter;
	private ProgressThread progressThread;
	private IEpicSynch mISynchEpic;
	private ProgressDialog dialog;
	private static Typeface tfNormal;
	private static Typeface tfBold;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.epic);
        //assign external fonts
	    tfNormal = Typeface.createFromAsset(getBaseContext().getAssets(), "font/Arial.ttf");
	    tfBold = Typeface.createFromAsset(getBaseContext().getAssets(), "font/ArialBold.ttf");
        Log.d("SDK VERSION", Long.toString(Build.VERSION.SDK_INT, 10));
		if(DEBUG) {
        	Log.d(TAG, "onCreate()");
        }
//        dbHelper = new EpicDBAdapter(this);
//        dbHelper.open();
        
//        Date date = new Date();
//        long t_now_seconds = date.getTime()/1000;
        
//        dbHelper.removeExpiredContents(t_now_seconds);
//        initializeGridView();
//        initializeListView();
//        dbHelper.close();
//        
        Intent q = new Intent(getApplicationContext(),LocationEpicService.class);
        startService(q);
        
        Intent s = new Intent(getApplicationContext(),EpicSynch.class);
        startService(s);
        
        bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        
        CheckBluetoothState();
        
//        registerReceiver(ScanModeChangedReceiver, new IntentFilter(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED));
//         
//		  registerReceiver(mReceiver, new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED));
    }
    

    private void CheckBluetoothState(){
        if(bluetoothAdapter == null) {
//            Toast.makeText(this, "Bluetooth NOT support", Toast.LENGTH_LONG).show();
        }
        else {
        	if (bluetoothAdapter.isEnabled()){
        		
        		Intent i = new Intent(getApplicationContext(),IOEpicService.class);
    	        startService(i);
    	        
//        		if(bluetoothAdapter.getScanMode()==BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
////        			Toast.makeText(this, "Bluetooth mode: Connectable and Discoverable", Toast.LENGTH_LONG).show();
//        			Intent i = new Intent(getApplicationContext(),IOEpicService.class);
//        	        startService(i);
//        		}
//        		else {
//        			Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
//        	        discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 0);
//        	        startActivityForResult(discoverableIntent, REQUEST_DISCOVERABLE_BT);
//        		}
        	}
        	else {
        		
        		Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
    	        startActivityForResult(discoverableIntent, REQUEST_DISCOVERABLE_BT);
        		
//        		Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
//    	        discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 0);
//    	        startActivityForResult(discoverableIntent, REQUEST_DISCOVERABLE_BT);
        	}
        }
    }
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    	if (requestCode == REQUEST_DISCOVERABLE_BT){
    		//######################################################################################################
    		// n.b.: http://hi-android.info/src/com/android/settings/bluetooth/RequestPermissionActivity.java.html #
    		// bluetooth enabled => RESULT_OK, bluetooth connectable and discoverable => RESULT_FIRST_USER         #
    		//######################################################################################################
    		if(resultCode == RESULT_OK || resultCode == RESULT_FIRST_USER) { 
//    			Toast.makeText(this, "Bluetooth mode: Connectable and Discoverable", Toast.LENGTH_LONG).show();
    			Intent i = new Intent(getApplicationContext(),IOEpicService.class);
    	        startService(i);
    		}
    		else { 
    			if(resultCode == RESULT_CANCELED){
//    				Toast.makeText(this, "Bluetooth not enabled\nEpic communication canceled!", Toast.LENGTH_LONG).show();
    			}
    			else {
    				Log.d("onActivityResult, request discoverable", "Unknown result code\nRESULT CODE = "+resultCode);
//    				Toast.makeText(this, "Unknown result code\nRESULT CODE = "+resultCode, Toast.LENGTH_LONG).show();
    			}
    		}
    	}
    }
       
    //########################
    //## BROADCAST RECEIVER ##
    //########################
	
//	// Create a BroadcastReceiver for Bluetooth ACTION_FOUND
//    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
//        public void onReceive(Context context, Intent intent) {
//            String action = intent.getAction();
//            Log.d("Bluetooth state", action);
//            String action_close_progress_dialog = "close.epic.progress.dialog";
//            // When discovery finds a device
//            if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
//                Bundle extra = intent.getExtras();
//                int state = extra.getInt(BluetoothAdapter.ACTION_STATE_CHANGED);
//                if(state == BluetoothAdapter.STATE_ON) {
//                	CheckBluetoothState();
//                }
//                else if (action.equals(action_close_progress_dialog)){
//                	Intent stopIntent = new Intent(getApplicationContext(), IOEpicService.class);
//    				stopService(stopIntent);
//                	dialog.dismiss();
//                }
//                else {
//                	Intent stopIntent = new Intent(getApplicationContext(), IOEpicService.class);
//    				stopService(stopIntent);
//                }
//            }
//        }
//    };
//    
//    private final BroadcastReceiver ScanModeChangedReceiver = new BroadcastReceiver(){
//    	@Override
//    	public void onReceive(Context context, Intent intent) {
//    		String action = intent.getAction();
//    		Intent stopIntent;
//    		if(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED.equals(action)) {
//    			int mode = intent.getIntExtra(BluetoothAdapter.EXTRA_SCAN_MODE, BluetoothAdapter.ERROR);
//    			switch(mode){
//    			case BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE:
//    				Intent i = new Intent(context, IOEpicService.class);
//                	startService(i);
//                	Log.d("bluetooth scan mode changed", "connectable discoverable");
//    				break;
//    			case BluetoothAdapter.SCAN_MODE_CONNECTABLE:
//    				stopIntent = new Intent(getApplicationContext(), IOEpicService.class);
//    				stopService(stopIntent);
//    				Log.d("bluetooth scan mode changed", "connectable");
//    				break;
//    			case BluetoothAdapter.SCAN_MODE_NONE:
//    				stopIntent = new Intent(getApplicationContext(), IOEpicService.class);
//    				stopService(stopIntent);
//    				Log.d("bluetooth scan mode changed", "mode none");
//    				break;
//    			default:
//    				stopIntent = new Intent(getApplicationContext(), IOEpicService.class);
//					stopService(stopIntent);
//					Log.d("bluetooth scan mode changed", action);
//					break;
//    			}
//            }
//    	}
//    };
    
     
    @Override
    protected void onDestroy() {
    	super.onDestroy();
 		if (dbHelper != null) {
 			dbHelper.close();
 		}
 	}
    
    @Override
    protected void onPause() {
    	if (dbHelper != null) {
 			dbHelper.close();
 		}
    	super.onPause();
    }
    
    @Override
    public void onResume(){
        super.onResume();
        if (dbHelper != null) {
 			dbHelper.open();
 		}
        else {
        	dbHelper = new EpicDBAdapter(this);
            dbHelper.open();
        }
        Date date = new Date();
        long t_now_seconds = date.getTime()/1000;
        dbHelper.removeExpiredContents(t_now_seconds);
//        dbHelper.close();
        initializeGridView();
        initializeListView();
        
        if(bluetoothAdapter == null) {
        	bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        	CheckBluetoothState();
        }
    }
    //#########################################
    //## INITIALIZE GRIDVIEW AND SET ADAPTER ##
    //#########################################
    private void initializeGridView() {
    	label_array[0] = getString(R.string.new_msg);
    	label_array[1] = getString(R.string.all_msg);
    	label_array[2] = getString(R.string.settings);
    	label_array[3] = getString(R.string.profile);
    	if(DEBUG) {
    		Log.d(TAG, "initializeGridView()");
    	}
        gridview = (GridView) findViewById(R.id.epic_gridview);
        gridview.setAdapter(new GridViewImageAdapter(Epic.this));
        
        // create intent for each Activity  
        final Intent intent_EpicMsg = new Intent(Epic.this, EpicNewMsg.class);
        final Intent intent_EpicMsgList = new Intent(Epic.this, EpicMsgListTab.class);
        final Intent intent_EpicProfile = new Intent(Epic.this, EpicProfile.class);
        final Intent intent_EpicSettings = new Intent(Epic.this, EpicSettings.class);
        
        // implement the setOnClickListener method instantiating a new OnItemClickListener object
        gridview.setOnItemClickListener(new OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
            	if (dbHelper != null) {
//        			dbHelper.close();
        		}
                switch(position){
                case NEW_MSG:
                	startActivity(intent_EpicMsg);
                	break;
                case ALL_MSG:
                	startActivity(intent_EpicMsgList);
                	break;
                case SETTINGS:
                	startActivity(intent_EpicSettings);
                	break;
                case PROFILE:
                	startActivity(intent_EpicProfile);
                	break;
                }
            }
        });
    }
    
    private class GridViewImageAdapter extends BaseAdapter {
    	private Integer[] mThumbIds = {
	            R.drawable.ic_epic_new_msg,  R.drawable.ic_epic_all_msgs,
	            R.drawable.ic_epic_settings, R.drawable.ic_epic_profile
    	};
    	private Context mContext;
    	public GridViewImageAdapter(Context c) {
            mContext = c;
        }
    	public int getCount() {
    		return mThumbIds.length;
    	}
    	public Object getItem(int position) {
    		return null;
    	}
    	public long getItemId(int position) {
    		return 0;
    	}
    	public View getView(int position, View convertView, ViewGroup parent) {
            if (convertView == null) {  // if it's not recycled, initialize some attributes
            	LayoutInflater inflater = getLayoutInflater();
        		convertView = inflater.inflate(R.layout.epic_gridview_element,parent,false);
            } 
            TextView custom_label = (TextView)convertView.findViewById(R.id.custom_label);
            custom_label.setText(label_array[position]);
            custom_label.setTextColor(getResources().getColor(R.color.White));
            custom_label.setTextSize(TypedValue.COMPLEX_UNIT_PX,15);
            custom_label.setTypeface(tfNormal);
    		ImageView custom_icon = (ImageView)convertView.findViewById(R.id.custom_icon);
            custom_icon.setImageResource(mThumbIds[position]);
            
            return convertView;
    	}
    }

    
  //###################################################
  //## INITIALIZE HORIZONTALLISTVIEW AND SET ADAPTER ##
  //###################################################
    String[] title_array;
    String[] msg_id_array;
    private ListAdapter adapter;
    
    public void initializeListView() {		
//		if (dbHelper != null) {
// 			dbHelper.open();
// 		}
//        else {
//        	dbHelper = new EpicDBAdapter(this);
//            dbHelper.open();
//        }
		
		// use the HorizontalListView instead of Gallery (n.b.: MIT copyright needed)
		myListView = null;
		myListView = (HorizontalListView) findViewById(R.id.myListView);
		

		//########
		cursor = dbHelper.getFilteredContentsByLoggedUsers();
		
		if(cursor!=null) {
//			startManagingCursor(cursor);
			// Now create a new list adapter bound to the cursor.
			// SimpleListAdapter is designed for binding to a Cursor.
			adapter = new SimpleCursorAdapter(this, R.layout.epic_gallery_item, cursor, 
					new String[] { EpicDBAdapter.MSG_TITLE },
					new int[] { R.id.epic_gallery_item_title });
			// Bind to our new adapter.
			myListView.setAdapter(adapter);
		}
		else {
			adapter = new SimpleCursorAdapter(this, R.layout.epic_gallery_item, null, 
					new String[] { EpicDBAdapter.MSG_CONTENT },
					new int[] { R.id.epic_gallery_item_title });
			// Bind to our new adapter.
			myListView.setAdapter(adapter);
		}
		//########
		
		// implement the setOnClickListener method instantiating a new OnItemClickListener object
        myListView.setOnItemClickListener(new OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
//            	dbHelper.open();
            	Cursor c = dbHelper.getMsgId(id);
        		String msg_id_to_query = c.getString(c.getColumnIndex(EpicDBAdapter.MSG_ID));
//        		dbHelper.close();
        		final Intent intentEpicShowMsg = new Intent(Epic.this, EpicShowMsg.class);
            	intentEpicShowMsg.putExtra("msg_id_to_query", msg_id_to_query);
            	startActivity(intentEpicShowMsg);
            }
        });
        
//        // implement the setOnClickListener method instantiating a new OnItemClickListener object
//        myListView.setOnItemLongClickListener(new OnItemLongClickListener() {
//			public boolean onItemLongClick(AdapterView<?> parent, View v, int position, long id) {
//				dbHelper.open();
//            	Cursor c = dbHelper.getMsgId(id);
//            	msg_id_to_remove = c.getString(c.getColumnIndex(EpicDBAdapter.MSG_ID));
//        		dbHelper.close();
//				registerForContextMenu(v);
//				return true;
//			}
//        });
        
        if (dbHelper != null) {
//			dbHelper.close();
		}
    }
    String msg_id_to_remove;
    
	//##################
    //## CONTEXT MENU ##
    //##################
	@Override
	public void onCreateContextMenu(ContextMenu menu, View v,
	                                ContextMenuInfo menuInfo) {
	  super.onCreateContextMenu(menu, v, menuInfo);
	  setContextMenuMsgId((String) v.getContentDescription());
	  MenuInflater inflater = getMenuInflater();
	  inflater.inflate(R.menu.remove_element_menu, menu);
	}
	
	private String context_menu_msg_id; 
	private void setContextMenuMsgId(String msg_id) {
		context_menu_msg_id = msg_id;
	}
	private String getContextMenuMsgId() {
		return context_menu_msg_id;
	}
	
	@Override
	public boolean onContextItemSelected(MenuItem item) {
		switch (item.getItemId()) {
	    case R.id.delete_msg: {
//	    	if(dbHelper!=null) {
//	        	dbHelper.open();
//	        }
//	        else {
//	        	dbHelper = new EpicDBAdapter(this);
//	        	dbHelper.open();
//	        }
	    	boolean deletionSucceeded = dbHelper.markAsDeleted(msg_id_to_remove);
	    	if(deletionSucceeded) {
	    		Log.d("Epic", "Epic message marked as deleted.");
	    		initializeListView();
	    	}
	    	else {
	    		Log.d("Epic", "Error in deleting this Epic message!");
	    	}
	        return deletionSucceeded;
	    }
	    case R.id.tag_msg: {
	    	Toast.makeText(getApplicationContext(), "Mark messages not yet available", 2000).show();
	        return true;
	    }
	  default:
	    return super.onContextItemSelected(item);
	  }
	}
	
   
    //#################
    //## OPTION MENU ##
    //#################
    @Override
	public boolean onCreateOptionsMenu(Menu menu) {
	    MenuInflater inflater = getMenuInflater();
	    inflater.inflate(R.menu.epic_menu, menu);
	    return true;
	}
	
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
	    // Handle item selection
	    switch (item.getItemId()) {
	    case R.id.epic_close_option:	 
	        Intent intent = new Intent(Intent.ACTION_MAIN);
	        intent.addCategory(Intent.CATEGORY_HOME);
	        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
	        startActivity(intent);
	        return true;
	    case R.id.epic_help_option:
	        showHelp();
	        return true;
//	    case R.id.epic_synch_option:
//            Intent r = new Intent(getApplicationContext(),EpicSynch.class);
//            startService(r);
//            dialog = ProgressDialog.show(Epic.this, "", "Loading. Please wait...", false);
//            dialog.show();
//            
////            bindService(r, mConnection,  BIND_AUTO_CREATE);
////            showDialog(PROGRESS_DIALOG);
	    default:
	        return super.onOptionsItemSelected(item);
	    }
	}
	
	private void showHelp() {
		Toast.makeText(Epic.this, "Drop to create a new message\nCrop to display messages", Toast.LENGTH_LONG).show();
	}
	
	//#######################
    //## SERVICE CONNECTION##
    //#######################
	
    private ServiceConnection mConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className,IBinder service) {
        	 mISynchEpic = IEpicSynch.Stub.asInterface(service);
        }
        public void onServiceDisconnected(ComponentName className) {
        	mISynchEpic = null;
        }
    };

	protected Dialog onCreateDialog(int id) {
		switch(id) {
        case PROGRESS_DIALOG:
            progressDialog = new ProgressDialog(Epic.this);
            progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
            progressDialog.setMessage("Loading...");
            return progressDialog;
        default:
            return null;
        }
    }
	@Override
    protected void onPrepareDialog(int id, Dialog dialog) {
        switch(id) {
        case PROGRESS_DIALOG:
            progressDialog.setProgress(0);
            progressThread = new ProgressThread(handler);
            progressThread.start();
        }
	}    
    // Define the Handler that receives messages from the thread and update the progress
    final Handler handler = new Handler() {
        public void handleMessage(Message msg) {
            int total = msg.arg1;
            progressDialog.setProgress(total);
            if (total >= 100){
                dismissDialog(PROGRESS_DIALOG);
                progressThread.setState(ProgressThread.STATE_DONE);
            }
        }
    };
        
    /** Nested class that performs progress calculations (counting) */
    private class ProgressThread extends Thread {
            Handler mHandler;
            final static int STATE_DONE = 0;
            final static int STATE_RUNNING = 1;
            int mState;
           
            ProgressThread(Handler h) {
                mHandler = h;
            }
           
            public void run() {
                mState = STATE_RUNNING;   
                while (mState == STATE_RUNNING) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        Log.e("ERROR", "Thread Interrupted");
                    }
                    Message msg = mHandler.obtainMessage();
                    if(mISynchEpic!= null){
	                    try {
							msg.arg1 = mISynchEpic.getPercentage();
						} catch (RemoteException e) {
							e.printStackTrace();
						}
                    }
                    mHandler.sendMessage(msg);
                    
                }
            }
            
            /* sets the current state for the thread,
             * used to stop the thread */
            public void setState(int state) {
                mState = state;
            }
        }
	

}
